/*
********************************************************************************
* Copyright (C) 2021, xiang.D <dx_65535@163.com>.
* All right reserved.
*
* File Name   : prototype.cc
* Author      :
* Version     : V1.0
* Description :
* Journal     : 2021-10-21 init v1.0
* Brief       : Blog: https://blog.csdn.net/qq_38750572?spm=1001.2014.3001.5343
* Others      :
                Compile command: g++ -Wl,--no-as-needed -std=c++11 builder.cc
********************************************************************************
*/
#include <iostream>
#include <string>

using namespace std;

class CPrototype
{
public:

    CPrototype() {}

    ~CPrototype() {}

    virtual CPrototype* Clone() = 0;
};

class CWukong : CPrototype
{
public:
    CWukong() : mAge(0), mHeightCM(100), mHair(10000), mLockRing(0), mFightCapacity (20)
    {

     }

    CWukong(CWukong *rhs)
    {
        mName = rhs->mName;
        mAge = rhs->mAge;
        mHeightCM = rhs->mHeightCM;
        mHair = rhs->mHair;
        mLockRing = rhs->mLockRing;
        mFightCapacity = rhs->mFightCapacity;
    }

    virtual ~CWukong() {}

    void SetName(string value) { mName = value; }

    void AddAge(int value) { mAge += value; }

    void SetHeight(int value) { mHeightCM = value; }

    void SetHair(int value) { mHair = value; }

    void PutLockRing() { mLockRing = 1; }

    void RemoveLockRing() { mLockRing = 0; }

    void SetFightCapacity(int value) { mFightCapacity = value; }

    string GetName() { return mName; }

    int GetAge() { return mAge; }

    int GetHeight() { return mHeightCM; }

    int GetHair() { return mHair; }

    int GetLockRing() { return mLockRing; }

    int GetFightCapacity() { return mFightCapacity; }

    CWukong* Clone()
    {
        return new CWukong(*this);
    }

private:
    string mName;
    int mAge;
    int mHeightCM;
    int mHair;
    bool mLockRing;
    int mFightCapacity;
};

static void learn_skills(CWukong *pMonkey)
{
    //After 11 years of study, Wukong's parameters change
    pMonkey->SetName("Wukong.Sun");
    pMonkey->AddAge(11);
    pMonkey->SetHeight(150);
    pMonkey->SetFightCapacity(80);
}

static void show_params(CWukong *pMonkey)
{
    cout << ">> " << pMonkey->GetName() << endl;
    cout << "Age: " << pMonkey->GetAge() << endl;
    cout << "Height(cm): " << pMonkey->GetHeight() << endl;
    cout << "Hair: " << pMonkey->GetHair() << endl;
    cout << "LockRing: " << pMonkey->GetLockRing() << endl;
    cout << "FightCapacity: " << pMonkey->GetFightCapacity() << endl;
    cout << "\n" << endl;
}

int main (int argc, char *argv[])
{
    CWukong *theWukong = new CWukong();
    //Before Learning, show params
    cout << "Before Learning" << endl;
    show_params(theWukong);

    //At the age of five, he went to learn skills
    theWukong->AddAge(5);
    theWukong->SetHeight(120);
    learn_skills(theWukong);
    //Return after Learning, show params
    show_params(theWukong);

    //Show multitasking skills
    cout << "Clone Wukong" << endl;
    CWukong *theWukong2 = theWukong->Clone();
    show_params(theWukong2);

    delete theWukong2;
    delete theWukong;
    return 0;
}